#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
几何模块

该模块提供了用于路径规划计算的几何实用函数。
"""

import numpy as np


def euclidean_distance(point1, point2):
    """
    计算两点之间的欧几里得距离。
    
    参数:
        point1 (tuple): 第一个点，格式为 (x, y)
        point2 (tuple): 第二个点，格式为 (x, y)
        
    返回:
        float: 欧几里得距离
    """
    x1, y1 = point1
    x2, y2 = point2
    return np.sqrt((x1 - x2)**2 + (y1 - y2)**2)


def check_line_intersection(line1, line2):
    """
    检查两条线段是否相交。
    
    参数:
        line1 (tuple): 第一条线段，格式为 ((x1, y1), (x2, y2))
        line2 (tuple): 第二条线段，格式为 ((x1, y1), (x2, y2))
        
    返回:
        bool: 如果线段相交返回True，否则返回False
    """
    # 提取线段端点
    (x1, y1), (x2, y2) = line1
    (x3, y3), (x4, y4) = line2
    
    # 计算行列式
    den = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)
    
    # 如果线段平行，则不相交
    if den == 0:
        return False
    
    ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / den
    ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / den
    
    # 如果交点在两条线段内
    return 0 <= ua <= 1 and 0 <= ub <= 1


def interpolate_points(point1, point2, num_points):
    """
    在两点之间插值生成中间点。
    
    参数:
        point1 (tuple): 起始点，格式为 (x, y)
        point2 (tuple): 终止点，格式为 (x, y)
        num_points (int): 要生成的中间点数量
        
    返回:
        list: 包含端点在内的插值点列表
    """
    x1, y1 = point1
    x2, y2 = point2
    
    # 生成参数值
    t_values = np.linspace(0, 1, num_points)
    
    # 插值点
    points = [(x1 + t * (x2 - x1), y1 + t * (y2 - y1)) for t in t_values]
    
    return points


def angle_between_points(from_point, to_point):
    """
    计算两点之间的角度（弧度）。
    
    参数:
        from_point (tuple): 起始点，格式为 (x, y)
        to_point (tuple): 终止点，格式为 (x, y)
        
    返回:
        float: 角度（弧度）
    """
    dx = to_point[0] - from_point[0]
    dy = to_point[1] - from_point[1]
    return np.arctan2(dy, dx)


def is_point_in_polygon(point, polygon_points):
    """
    检查点是否在多边形内（射线投射算法）。
    
    参数:
        point (tuple): 要检查的点，格式为 (x, y)
        polygon_points (list): 多边形顶点列表，格式为 [(x1, y1), (x2, y2), ...]
        
    返回:
        bool: 如果点在多边形内返回True，否则返回False
    """
    x, y = point
    n = len(polygon_points)
    inside = False
    
    p1x, p1y = polygon_points[0]
    for i in range(n + 1):
        p2x, p2y = polygon_points[i % n]
        
        if y > min(p1y, p2y) and y <= max(p1y, p2y) and x <= max(p1x, p2x):
            if p1y != p2y:
                xinters = (y - p1y) * (p2x - p1x) / (p2y - p1y) + p1x
            if p1x == p2x or x <= xinters:
                inside = not inside
                
        p1x, p1y = p2x, p2y
        
    return inside 